home *** CD-ROM | disk | FTP | other *** search
/ Monster Media 1996 #15 / Monster Media Number 15 (Monster Media)(July 1996).ISO / netmail / rnr214.zip / RNRKILL.PAS < prev    next >
Pascal/Delphi Source File  |  1995-12-31  |  30KB  |  1,178 lines

  1. unit rnrkill;
  2.  
  3. {
  4.  
  5. rnrkill.pas - rnr killfile and antikillfile processing
  6.  
  7. }
  8.  
  9. {$I rnr-def.pas}
  10.  
  11. interface
  12.  
  13. uses genericf,rnrglob,rnrconf,rnrfunc,rnrio,rnrproc,rnrfile;
  14.  
  15. const
  16.   yesbackupkill=true;
  17.   nobackupkill=false;
  18.  
  19.   maxkillheaderlen=18;
  20.   maxkilltextlen=75;
  21.  
  22. type
  23.   killheadert=string[maxkillheaderlen];
  24.   killtextt=string[maxkilltextlen];
  25.   killt=record
  26.           header: killheadert;
  27.           text: killtextt;
  28.         end;
  29.   killsarr=array[1..maxkills] of killt;
  30.   killsarrp=^killsarr;
  31.  
  32. var
  33.   killsp: killsarrp;
  34.   antikillsp: killsarrp;
  35.  
  36.   groupkillsp: killsarrp;
  37.   groupantikillsp: killsarrp;
  38.  
  39. procedure addtokill(header,words: string; isglobal: boolean);
  40. procedure addtoantikill(header,words: string; isglobal: boolean);
  41.  
  42. procedure readinkill(backup: boolean);
  43. procedure readinantikill(backup: boolean);
  44.  
  45. procedure groupinitkills;
  46. procedure groupinitantikills;
  47.  
  48. function artkilled(subject, from, refs, fn: string): boolean;
  49. function artantikilled(subject, from, refs, fn: string): boolean;
  50.  
  51.  
  52. implementation
  53.  
  54. var
  55.   killfn,antikillfn: pathstring;
  56.   killfileinmem, antikillfileinmem: boolean;
  57.   numkills, numantikills: integer;
  58.   groupnumkills, groupnumantikills: integer;
  59.   groupkillfileinmem, groupantikillfileinmem: boolean;
  60.   nonglobalkills, nonglobalantikills: boolean;
  61.  
  62. function killseparator(s: string): boolean;
  63.  
  64. begin
  65.   killseparator := (parseheadername(s)='Newsgroups') or (copy(s,1,1)=':');
  66. end;
  67.  
  68. {$ifdef fixedkill}
  69. procedure addtosomekill(usekill: boolean; var somekillf: file;
  70.  header,words: string; isglobal: boolean);
  71.  
  72. var
  73.   spaceneeded: integer;
  74.   i,j: integer;
  75.   s: string;
  76.   tempf: text;
  77.   newsomekillwritten: boolean;
  78.   nonglobalsomekills: boolean;
  79.   numsomekills: integer;
  80.   somekillsubjsp,somekillfromsp,somekilltextp: killsarrp;
  81.  
  82. begin
  83.   if usekill then
  84.     begin
  85.       xwritelns('Updating kill file...');
  86.       nonglobalsomekills := nonglobalkills;
  87.       numsomekills := numkills;
  88.       somekillsubjsp := killsubjsp;
  89.       somekillfromsp := killfromsp;
  90.       somekilltextp := killtextp;
  91.     end
  92.   else
  93.     begin
  94.       xwritelns('Updating antikill file...');
  95.       nonglobalsomekills := nonglobalantikills;
  96.       numsomekills := numantikills;
  97.       somekillsubjsp := antikillsubjsp;
  98.       somekillfromsp := antikillfromsp;
  99.       somekilltextp := antikilltextp;
  100.     end;
  101.  
  102.   spaceneeded := 1;
  103.   if not isglobal then
  104.     if not nonglobalsomekills then
  105.       spaceneeded := 2;
  106.  
  107.   if numsomekills+spaceneeded<=maxkills then
  108.     begin
  109.       if isglobal then
  110.         begin
  111.           for i := numsomekills downto 1 do
  112.             somekilltextp^[i+1] := somekilltextp^[i];
  113.           somekilltextp^[1] := header+': '+words;
  114.         end
  115.       else if spaceneeded=2 then
  116.         begin
  117.           somekilltextp^[numsomekills+1] := ': '+currsource;
  118.           somekilltextp^[numsomekills+2] := header+': '+words;
  119.         end
  120.       else
  121.         begin
  122.           for i := 1 to numsomekills do
  123.             begin
  124.               s := somekilltextp^[i];
  125.               if killseparator(s) and (parseheadervalue(s)=currsource) then
  126.                 begin
  127.                   for j := numsomekills downto i+1 do
  128.                     somekilltextp^[j+1] := somekilltextp^[j];
  129.                   somekilltextp^[i+1] := header+': '+words;
  130.                 end;
  131.             end;
  132.         end;
  133.       if usekill then
  134.         inc(numkills,spaceneeded)
  135.       else
  136.         inc(numantikills,spaceneeded);
  137.       inc(numsomekills,spaceneeded);
  138.     end
  139.   else
  140.  
  141. {it definitely won't all fit in memory now}
  142.  
  143.     if usekill then
  144.       killfileinmem := false
  145.     else
  146.       antikillfileinmem := false;
  147.  
  148.   if header='Subject' then
  149.     begin
  150.       if numsubjks<maxkills then
  151.         begin
  152.           inc(numsubjks);
  153.           killsubjsp^[numsubjks] := words;
  154.         end
  155.       else
  156. {}{} {should delete the oldest one}
  157.         warn('kill file too large');
  158.     end
  159.   else
  160.     begin
  161.       if numfromks<maxkills then
  162.         begin
  163.           inc(numfromks);
  164.           killfromsp^[numfromks] := words;
  165.         end
  166.       else
  167. {}{} {should delete the oldest one}
  168.         warn('kill file too large');
  169.     end;
  170.  
  171.   if haskillfile then
  172.     begin
  173.       newsomekillwritten := false;
  174.       assign(tempf,withbackslash(temporarydir)+userid);
  175.       reset(killf);
  176.       rewrite(tempf);
  177.       if isglobal then
  178.         begin
  179.           writeln(tempf,header,': ',words);
  180.           newsomekillwritten := true;
  181.         end;
  182.       while not eof(killf) do
  183.         begin
  184.           readln(killf,s);
  185.           if killseparator(s) then
  186.             begin
  187.               writeln(tempf,': ',parseheadervalue(s));
  188.               if parseheadervalue(s)=currsource then
  189.                 begin
  190.                   writeln(tempf,header,': ',words);
  191.                   newsomekillwritten := true;
  192.                 end;
  193.             end
  194.           else
  195.             writeln(tempf,s);
  196.         end;
  197.       if not newsomekillwritten then {this group had no kill information}
  198.         begin
  199.           writeln(tempf,': ',currsource);
  200.           writeln(tempf,header,': ',words);
  201.           newsomekillwritten := true;
  202.         end;
  203.       close(killf);
  204.       close(tempf);
  205.       reset(tempf);
  206.       rewrite(killf);
  207.       while not eof(tempf) do
  208.         begin
  209.           readln(tempf,s);
  210.           writeln(killf,s);
  211.         end;
  212.       close(tempf);
  213.       close(killf);
  214.  
  215.       erase(tempf);
  216.     end
  217.   else
  218.     begin
  219.       haskillfile := true;
  220.       assign(killf,killfn);
  221.       rewrite(killf);
  222.       if not isglobal then
  223.         writeln(killf,': ',currsource);
  224.       writeln(killf,header,': ',words);
  225.     end;
  226.  
  227.   reset(killf);
  228. end;
  229. {$endif} {fixedkill}
  230.  
  231. procedure addtokill;
  232.  
  233. var
  234.   spaceneeded: integer;
  235.   i,j: integer;
  236.   s: string;
  237.   tempf: text;
  238.   newkillwritten: boolean;
  239.  
  240. begin
  241.   xwritelns('Updating kill file...');
  242.  
  243.   spaceneeded := 1;
  244.   if not isglobal then
  245.     if not nonglobalkills then
  246.       spaceneeded := 2;
  247.  
  248.   if numkills+spaceneeded<=maxkills then
  249.     begin
  250.       if isglobal then
  251.         begin
  252.           for i := numkills downto 1 do
  253.             killsp^[i+1] := killsp^[i];
  254.           killsp^[1].header := header;
  255.           killsp^[1].text := words;
  256.         end
  257.       else if spaceneeded=2 then
  258.         begin
  259.           killsp^[numkills+1].header := ':';
  260.           killsp^[numkills+1].text := currsource;
  261.           killsp^[numkills+2].header := header;
  262.           killsp^[numkills+2].text := words;
  263.         end
  264.       else
  265.         begin
  266.           for i := 1 to numkills do
  267.             begin
  268.               if killsp^[i].header=':' then
  269.                 if killsp^[i].text=currsource then
  270.                   begin
  271.                     for j := numkills downto i+1 do
  272.                       killsp^[j+1] := killsp^[j];
  273.                     killsp^[i+1].header := header;
  274.                     killsp^[i+1].text := words;
  275.                   end;
  276.             end;
  277.         end;
  278.       inc(numkills,spaceneeded);
  279.     end
  280.   else
  281.     killfileinmem := false;  {it definitely won't all fit in memory now}
  282.  
  283.   if groupnumkills<maxkills then
  284.     begin
  285.       inc(groupnumkills);
  286.       groupkillsp^[groupnumkills].header := header;
  287.       groupkillsp^[groupnumkills].text := words;
  288.     end
  289.   else
  290.     begin
  291. {}{} {should delete the oldest one}
  292.       warn('kill file too large');
  293.     end;
  294.  
  295.   if haskillfile then
  296.     begin
  297.       newkillwritten := false;
  298.       assign(tempf,withbackslash(temporarydir)+userid);
  299.       reset(killf);
  300.       rewrite(tempf);
  301.  
  302.       if isglobal then
  303.         begin
  304.           writeln(tempf,header,': ',words);
  305.           newkillwritten := true;
  306.         end;
  307.  
  308.       while not eof(killf) do
  309.         begin
  310.           readln(killf,s);
  311.           if killseparator(s) and not newkillwritten then
  312.             begin
  313.               writeln(tempf,': ',parseheadervalue(s));
  314.               if parseheadervalue(s)=currsource then
  315.                 begin
  316.                   writeln(tempf,header,': ',words);
  317.                   newkillwritten := true;
  318.                 end;
  319.             end
  320.           else
  321.             writeln(tempf,s);
  322.         end;
  323.  
  324.       if not newkillwritten then {this group had no kill information}
  325.         begin
  326.           writeln(tempf,': ',currsource);
  327.           writeln(tempf,header,': ',words);
  328.           newkillwritten := true;
  329.         end;
  330.  
  331.       close(killf);
  332.       close(tempf);
  333.  
  334.       reset(tempf);
  335.       rewrite(killf);
  336.       while not eof(tempf) do
  337.         begin
  338.           readln(tempf,s);
  339.           writeln(killf,s);
  340.         end;
  341.       close(tempf);
  342.       close(killf);
  343.  
  344.       erase(tempf);
  345.     end
  346.   else
  347.     begin
  348.       haskillfile := true;
  349.       assign(killf,killfn);
  350.       rewrite(killf);
  351.       if not isglobal then
  352.         writeln(killf,': ',currsource);
  353.       writeln(killf,header,': ',words);
  354.     end;
  355.  
  356.   reset(killf);
  357. end;
  358.  
  359. procedure addtoantikill;
  360.  
  361. var
  362.   spaceneeded: integer;
  363.   i,j: integer;
  364.   s: string;
  365.   tempf: text;
  366.   newantikillwritten: boolean;
  367.  
  368. begin
  369.   xwritelns('Updating antikill file...');
  370.  
  371.   spaceneeded := 1;
  372.   if not isglobal then
  373.     if not nonglobalantikills then
  374.       spaceneeded := 2;
  375.  
  376.   if numantikills+spaceneeded<=maxkills then
  377.     begin
  378.       if isglobal then
  379.         begin
  380.           for i := numantikills downto 1 do
  381.             antikillsp^[i+1] := antikillsp^[i];
  382.           antikillsp^[1].header := header;
  383.           antikillsp^[1].text := words;
  384.         end
  385.       else if spaceneeded=2 then
  386.         begin
  387.           antikillsp^[numantikills+1].header := ':';
  388.           antikillsp^[numantikills+1].text := currsource;
  389.           antikillsp^[numantikills+2].header := header;
  390.           antikillsp^[numantikills+2].text := words;
  391.         end
  392.       else
  393.         begin
  394.           for i := 1 to numantikills do
  395.             begin
  396.               if antikillsp^[i].header=':' then
  397.                 if antikillsp^[i].text=currsource then
  398.                   begin
  399.                     for j := numantikills downto i+1 do
  400.                       antikillsp^[j+1] := antikillsp^[j];
  401.                     antikillsp^[i+1].header := header;
  402.                     antikillsp^[i+1].text := words;
  403.                   end;
  404.             end;
  405.         end;
  406.       inc(numantikills,spaceneeded);
  407.     end
  408.   else
  409.     antikillfileinmem := false;  {it definitely won't all fit in memory now}
  410.  
  411.   if groupnumantikills<maxkills then
  412.     begin
  413.       inc(groupnumantikills);
  414.       groupantikillsp^[groupnumantikills].header := header;
  415.       groupantikillsp^[groupnumantikills].text := words;
  416.     end
  417.   else
  418.     begin
  419. {}{} {should delete the oldest one}
  420.       warn('antikill file too large');
  421.     end;
  422.  
  423.   if hasantikillfile then
  424.     begin
  425.       newantikillwritten := false;
  426.       assign(tempf,withbackslash(temporarydir)+userid);
  427.       reset(antikillf);
  428.       rewrite(tempf);
  429.  
  430.       if isglobal then
  431.         begin
  432.           writeln(tempf,header,': ',words);
  433.           newantikillwritten := true;
  434.         end;
  435.  
  436.       while not eof(antikillf) do
  437.         begin
  438.           readln(antikillf,s);
  439.           if killseparator(s) and not newantikillwritten then
  440.             begin
  441.               writeln(tempf,': ',parseheadervalue(s));
  442.               if parseheadervalue(s)=currsource then
  443.                 begin
  444.                   writeln(tempf,header,': ',words);
  445.                   newantikillwritten := true;
  446.                 end;
  447.             end
  448.           else
  449.             writeln(tempf,s);
  450.         end;
  451.  
  452.       if not newantikillwritten then {this group had no antikill information}
  453.         begin
  454.           writeln(tempf,': ',currsource);
  455.           writeln(tempf,header,': ',words);
  456.           newantikillwritten := true;
  457.         end;
  458.  
  459.       close(antikillf);
  460.       close(tempf);
  461.  
  462.       reset(tempf);
  463.       rewrite(antikillf);
  464.       while not eof(tempf) do
  465.         begin
  466.           readln(tempf,s);
  467.           writeln(antikillf,s);
  468.         end;
  469.       close(tempf);
  470.       close(antikillf);
  471.  
  472.       erase(tempf);
  473.     end
  474.   else
  475.     begin
  476.       hasantikillfile := true;
  477.       assign(antikillf,antikillfn);
  478.       rewrite(antikillf);
  479.       if not isglobal then
  480.         writeln(antikillf,': ',currsource);
  481.       writeln(antikillf,header,': ',words);
  482.     end;
  483.  
  484.   reset(antikillf);
  485. end;
  486.  
  487. {$ifdef oldaddtoantikill}
  488.  
  489. procedure addtoantikill(header,words: string; isglobal: boolean);
  490.  
  491. var
  492.   s: string;
  493.   tempf: text;
  494.   newantikillwritten: boolean;
  495.  
  496. begin
  497.   xwritelns('Updating antikill file...');
  498.  
  499.   if numantikills<maxkills then
  500.     begin
  501.       inc(numantikills);
  502.       antikilltextp^[numantikills] := header+': '+words;
  503.     end
  504.   else
  505.     antikillfileinmem := false;
  506.  
  507.   if header='Subject' then
  508.     begin
  509.       if numsubjaks<maxkills then
  510.         begin
  511.           inc(numsubjaks);
  512.           antikillsubjsp^[numsubjaks] := words;
  513.         end
  514.       else
  515. {}{} {should delete the oldest one?}
  516.         warn('antikill file too large');
  517.     end
  518.   else
  519.     begin
  520.       if numfromaks<maxkills then
  521.         begin
  522.           inc(numfromaks);
  523.           antikillfromsp^[numfromaks] := words;
  524.         end
  525.       else
  526. {}{} {should delete the oldest one?}
  527.         warn('antikill file too large');
  528.     end;
  529.  
  530.   if hasantikillfile then
  531.     begin
  532.       newantikillwritten := false;
  533.       assign(tempf,withbackslash(temporarydir)+userid);
  534.       reset(antikillf);
  535.       rewrite(tempf);
  536.       if isglobal then
  537.         begin
  538.           writeln(tempf,header,': ',words);
  539.           newantikillwritten := true;
  540.         end;
  541.       while not eof(antikillf) do
  542.         begin
  543.           readln(antikillf,s);
  544.           if killseparator(s) then
  545.             begin
  546.               writeln(tempf,': ',parseheadervalue(s));
  547.               if parseheadervalue(s)=currsource then
  548.                 begin
  549.                   writeln(tempf,header,': ',words);
  550.                   newantikillwritten := true;
  551.                 end;
  552.             end
  553.           else
  554.             writeln(tempf,s);
  555.         end;
  556.       if not newantikillwritten then {this group had no antikill information}
  557.         begin
  558.           writeln(tempf,': ',currsource);
  559.           writeln(tempf,header,': ',words);
  560.           newantikillwritten := true;
  561.         end;
  562.       close(antikillf);
  563.       close(tempf);
  564.       reset(tempf);
  565.       rewrite(antikillf);
  566.       while not eof(tempf) do
  567.         begin
  568.           readln(tempf,s);
  569.           writeln(antikillf,s);
  570.         end;
  571.       close(tempf);
  572.       close(antikillf);
  573.  
  574.       erase(tempf);
  575.     end
  576.   else
  577.     begin
  578.       hasantikillfile := true;
  579.       assign(antikillf,antikillfn);
  580.       rewrite(antikillf);
  581.       if not isglobal then
  582.         writeln(antikillf,': ',currsource);
  583.       writeln(antikillf,header,': ',words);
  584.     end;
  585.  
  586.   reset(antikillf);
  587. end;
  588. {$endif}
  589.  
  590. procedure readinkill;
  591.  
  592. var
  593.   s: string;
  594.   tempf: text;
  595.  
  596. begin
  597.   killfileinmem := true;
  598.   numkills := 0;
  599.  
  600.   if haskillfile then
  601.     close(killf);
  602.  
  603.   haskillfile := true;
  604.  
  605.   killfn := home+'\kill';
  606.   safereset(killf,killfn);
  607.   if fileresult<>0 then
  608.     begin
  609.       haskillfile := false;
  610.       xwritelns('(no kill file found)');
  611.     end;
  612.  
  613.   if haskillfile then
  614.     begin
  615.       if backup then
  616.         begin
  617.           xwritelns('Backing up kill file...');
  618.           assign(tempf,home+'\kill.bak');
  619.           rewrite(tempf);
  620.         end
  621.       else
  622.         xwritelns('Reading in kill file...');
  623.  
  624.       reset(killf);
  625.       while not eof(killf) do
  626.         begin
  627.           readln(killf,s);
  628.           if backup then
  629.             writeln(tempf,s);
  630.           if numkills<maxkills then
  631.             begin
  632.               inc(numkills);
  633.               if killseparator(s) then
  634.                 killsp^[numkills].header := ':'
  635.               else
  636.                 killsp^[numkills].header := parseheadername(s);
  637.               killsp^[numkills].text := parseheadervalue(s);
  638.             end
  639.           else
  640.             killfileinmem := false;
  641.         end;
  642.  
  643.       if backup then
  644.         close(tempf);
  645.  
  646.       reset(killf);
  647.     end;
  648. end;
  649.  
  650. procedure readinantikill;
  651.  
  652. var
  653.   s: string;
  654.   tempf: text;
  655.  
  656. begin
  657.   if hasantikillfile then
  658.     close(antikillf);
  659.  
  660.   antikillfileinmem := true;
  661.   numantikills := 0;
  662.  
  663.   hasantikillfile := true;
  664.  
  665.   antikillfn := home+'\antikill';
  666.   safereset(antikillf,antikillfn);
  667.   if fileresult<>0 then
  668.     begin
  669.       hasantikillfile := false;
  670.       xwritelns('(no antikill file found)');
  671.     end;
  672.  
  673.   if hasantikillfile then
  674.     begin
  675.       if backup then
  676.         begin
  677.           xwritelns('Backing up antikill file...');
  678.           assign(tempf,home+'\antikill.bak');
  679.           rewrite(tempf);
  680.         end
  681.       else
  682.         xwritelns('Reading in antikill file...');
  683.  
  684.       reset(antikillf);
  685.       while not eof(antikillf) do
  686.         begin
  687.           readln(antikillf,s);
  688.           if backup then
  689.             writeln(tempf,s);
  690.           if numantikills<maxkills then
  691.             begin
  692.               inc(numantikills);
  693.               if killseparator(s) then
  694.                 antikillsp^[numantikills].header := ':'
  695.               else
  696.                 antikillsp^[numantikills].header := parseheadername(s);
  697.               antikillsp^[numantikills].text := parseheadervalue(s);
  698.             end
  699.           else
  700.             antikillfileinmem := false;
  701.         end;
  702.  
  703.       if backup then
  704.         close(tempf);
  705.  
  706.       reset(antikillf);
  707.     end;
  708. end;
  709.  
  710. procedure groupinitkills;
  711.  
  712. var
  713.   akill: killt;
  714.   killgroup: string;
  715.   inglobals: boolean;
  716.   killline: integer;
  717.   sizewarned: boolean;
  718.  
  719.     function killeof: boolean;
  720.  
  721.     begin
  722.       if killfileinmem then
  723.         killeof := (killline>=numkills)
  724.       else
  725.         killeof := eof(killf);
  726.     end;
  727.  
  728.     procedure getnextkillline(var akill: killt);
  729.  
  730.     var
  731.       s: string;
  732.  
  733.     begin
  734.       if killfileinmem then
  735.         begin
  736.           inc(killline);
  737.           akill := killsp^[killline];
  738.         end
  739.       else
  740.         begin
  741.           readln(killf,s);
  742.           if killseparator(s) then
  743.             akill.header := ':'
  744.           else
  745.             akill.header := parseheadername(s);
  746.           akill.text := parseheadervalue(s);
  747.         end;
  748.     end;
  749.  
  750. begin { groupinitkills }
  751.  
  752. {read in kill file for this group}
  753.  
  754.   groupnumkills := 0;
  755.   nonglobalkills := false;
  756.  
  757.   killline := 0;
  758.   inglobals := true;
  759.  
  760.   sizewarned := false;
  761.  
  762.   if haskillfile then
  763.     begin
  764.       if not killfileinmem then
  765.         begin
  766.           notquietlns('reading in kill file...');
  767.           reset(killf);
  768.         end;
  769.  
  770. {allow defaults to come before the first `: newsgroup' line}
  771.  
  772.       killgroup := currsource;
  773.       while not killeof do
  774.         begin
  775.           getnextkillline(akill);
  776.  
  777. {if it's a new `: newsgroup' selection, then check it - otherwise, process}
  778.  
  779.           if akill.header=':' then
  780.             begin
  781.               killgroup := akill.text;
  782.               inglobals := false;
  783.             end
  784.           else if killgroup=currsource then
  785.             begin
  786.               if showkills then
  787.                 xwritelnssss('kill: ',
  788.                  akill.header,' ',akill.text)
  789.               else
  790.                 begin
  791.                   if showsubjectkills then
  792.                     if akill.header='Subject' then
  793.                       xwritelnssss('kill: ',
  794.                        akill.header,' ',akill.text);
  795.                   if showfromkills then
  796.                     if akill.header='From' then
  797.                       xwritelnssss('kill: ',
  798.                        akill.header,' ',akill.text);
  799.                 end;
  800.  
  801.               if groupnumkills<maxkills then
  802.                 begin
  803.                   inc(groupnumkills);
  804.                   groupkillsp^[groupnumkills] := akill;
  805.                   if not inglobals then
  806.                     nonglobalkills := true;
  807.                 end
  808.               else
  809.                 begin
  810. {}{} {too many kills - ignore}
  811. {}{} {should discard the oldest one}
  812.                   if not sizewarned then
  813.                     warn('kill file is larger than memory allocated');
  814.                   sizewarned := true;
  815.                 end;
  816.             end;
  817.         end;
  818.     end;
  819. end;
  820.  
  821. procedure groupinitantikills;
  822.  
  823. var
  824.   anantikill: killt;
  825.   antikillgroup: string;
  826.   inglobals: boolean;
  827.   antikillline: integer;
  828.   sizewarned: boolean;
  829.  
  830.     function antikilleof: boolean;
  831.  
  832.     begin
  833.       if antikillfileinmem then
  834.         antikilleof := (antikillline>=numantikills)
  835.       else
  836.         antikilleof := eof(antikillf);
  837.     end;
  838.  
  839.     procedure getnextantikillline(var anantikill: killt);
  840.  
  841.     var
  842.       s: string;
  843.  
  844.     begin
  845.       if antikillfileinmem then
  846.         begin
  847.           inc(antikillline);
  848.           anantikill := antikillsp^[antikillline];
  849.         end
  850.       else
  851.         begin
  852.           readln(antikillf,s);
  853.           if killseparator(s) then
  854.             anantikill.header := ':'
  855.           else
  856.             anantikill.header := parseheadername(s);
  857.           anantikill.text := parseheadervalue(s);
  858.         end;
  859.     end;
  860.  
  861. begin { groupinitantikills }
  862.  
  863. {read in antikill file for this group}
  864.  
  865.   groupnumantikills := 0;
  866.   nonglobalantikills := false;
  867.  
  868.   antikillline := 0;
  869.   inglobals := true;
  870.  
  871.   sizewarned := false;
  872.  
  873.   if hasantikillfile then
  874.     begin
  875.       if not antikillfileinmem then
  876.         begin
  877.           notquietlns('reading in antikill file...');
  878.           reset(antikillf);
  879.         end;
  880.  
  881. {allow defaults to come before the first `: newsgroup' line}
  882.  
  883.       antikillgroup := currsource;
  884.       while not antikilleof do
  885.         begin
  886.           getnextantikillline(anantikill);
  887.  
  888. {if it's a new `: newsgroup' selection, then check it - otherwise, process}
  889.  
  890.           if anantikill.header=':' then
  891.             begin
  892.               antikillgroup := anantikill.text;
  893.               inglobals := false;
  894.             end
  895.           else if antikillgroup=currsource then
  896.             begin
  897.  
  898.               if showantikills then
  899.                 xwritelnssss('antikill: ',
  900.                  anantikill.header,' ',anantikill.text)
  901.               else
  902.                 begin
  903.                   if showsubjectantikills then
  904.                     if anantikill.header='Subject' then
  905.                       xwritelnssss('antikill: ',
  906.                        anantikill.header,' ',anantikill.text);
  907.                   if showfromantikills then
  908.                     if anantikill.header='From' then
  909.                       xwritelnssss('antikill: ',
  910.                        anantikill.header,' ',anantikill.text);
  911.                 end;
  912.  
  913.               if groupnumantikills<maxkills then
  914.                 begin
  915.                   inc(groupnumantikills);
  916.                   groupantikillsp^[groupnumantikills] := anantikill;
  917.                   if not inglobals then
  918.                     nonglobalantikills := true;
  919.                 end
  920.               else
  921.                 begin
  922. {}{} {too many antikills - ignore}
  923. {}{} {should discard the oldest one}
  924.                   if not sizewarned then
  925.                     warn('antikill file is larger than memory allocated');
  926.                   sizewarned := true;
  927.                 end;
  928.             end;
  929.         end;
  930.     end;
  931. end;
  932.  
  933. function killmatch(killtext,headertext: string;
  934.  caseinsensitive,substring: boolean): boolean;
  935.  
  936. { if caseinsensitive, then headertext is already uppercased }
  937.  
  938. begin
  939.   if caseinsensitive then
  940.     if substring then
  941.       killmatch := textintext(upper(killtext),headertext)
  942.     else
  943.       killmatch := (upper(killtext)=headertext)
  944.   else
  945.     if substring then
  946.       killmatch := textintext(killtext,headertext)
  947.     else
  948.       killmatch := (killtext=headertext);
  949. end;
  950.  
  951. {$ifdef oldkill}
  952. function subjkilled(subject: string): boolean;
  953.  
  954. var
  955.   result: boolean;
  956.   i: integer;
  957.   noresubject: string;
  958.  
  959. begin
  960.   result := false;
  961.  
  962. { subject matching always done modulo Re: }
  963.  
  964.   noresubject := nore(subject);
  965.  
  966.   if caseinsensitivekill then
  967.     noresubject := upper(noresubject);
  968.  
  969.   for i := 1 to numsubjks do
  970.     if not result then
  971.       result := killmatch(killsubjsp^[i],noresubject,
  972.        caseinsensitivekill,substringsubjectkill);
  973.   subjkilled := result;
  974. end;
  975.  
  976. function fromkilled(from: string): boolean;
  977.  
  978. var
  979.   result: boolean;
  980.   i: integer;
  981.   newfrom: string;
  982.  
  983. begin
  984.   result := false;
  985.  
  986. {From: match if that address found anywhere - so that if they change their}
  987. {posting software or whatever you'll still find it.}
  988.  
  989.   newfrom := from;
  990.  
  991.   if caseinsensitivekill then
  992.     newfrom := upper(newfrom);
  993.  
  994.   for i := 1 to numfromks do
  995.     if not result then
  996.       result := killmatch(killfromsp^[i],newfrom,
  997.        caseinsensitivekill,substringfromkill);
  998.  
  999.   fromkilled := result;
  1000. end;
  1001. {$endif}
  1002.  
  1003. function artkilled;
  1004.  
  1005. var
  1006.   result: boolean;
  1007.  
  1008.   whichkillline: integer;
  1009.   upsubject: string;
  1010.   upfrom: string;
  1011.   whichkill: integer;
  1012.  
  1013.   oneartheader: string;
  1014.  
  1015.   onekillheader: string;
  1016.   onekilltext: string;
  1017.  
  1018.   upkilltext: string;
  1019.  
  1020. begin
  1021.   result := false;
  1022.  
  1023.   upsubject := subject;
  1024.   if caseinsensitivekill then
  1025.     upsubject := upper(upsubject);
  1026.  
  1027.   upfrom := from;
  1028.   if caseinsensitivekill then
  1029.     upfrom := upper(upfrom);
  1030.  
  1031.   for whichkill := 1 to groupnumkills do
  1032.     if not result then
  1033.       begin
  1034.         onekillheader := lower(groupkillsp^[whichkill].header);
  1035.         onekilltext := groupkillsp^[whichkill].text;
  1036.         upkilltext := upper(onekilltext);
  1037.  
  1038.         if onekillheader='subject' then
  1039.           result := killmatch(onekilltext,upsubject,
  1040.            caseinsensitivekill,substringsubjectkill)
  1041.         else if onekillheader='from' then
  1042.           result := killmatch(onekilltext,upfrom,
  1043.            caseinsensitivekill,substringfromkill)
  1044.         else if onekillheader='references' then
  1045.           result := killmatch(upkilltext,upper(refs),false,true)
  1046.         else if fn<>'' then
  1047.           begin
  1048.             if showdebug('slowkill') then
  1049.               xwritelnssss('going to disk (',fn,') for header ',onekillheader);
  1050.  
  1051.             oneartheader := getheaderline(fn,onekillheader+':');
  1052.             if caseinsensitivekill then
  1053.               oneartheader := upper(oneartheader);
  1054.             if oneartheader<>'' then
  1055.               result := killmatch(
  1056.                onekilltext,oneartheader,caseinsensitivekill,true);
  1057.           end;
  1058.       end;
  1059.  
  1060.   artkilled := result;
  1061. end;
  1062.  
  1063. {$ifdef oldkill}
  1064. function subjantikilled(subject: string): boolean;
  1065.  
  1066. var
  1067.   result: boolean;
  1068.   i: integer;
  1069.   noresubject: string;
  1070.  
  1071. begin
  1072.   result := false;
  1073.  
  1074. { subject matching always done modulo Re: }
  1075.  
  1076.   noresubject := nore(subject);
  1077.  
  1078.   if caseinsensitiveantikill then
  1079.     noresubject := upper(noresubject);
  1080.  
  1081.   for i := 1 to numsubjaks do
  1082.     if not result then
  1083.       result := killmatch(antikillsubjsp^[i],noresubject,
  1084.        caseinsensitiveantikill,substringsubjectantikill);
  1085.  
  1086.   subjantikilled := result;
  1087. end;
  1088.  
  1089. function fromantikilled(from: string): boolean;
  1090.  
  1091. var
  1092.   result: boolean;
  1093.   i: integer;
  1094.   newfrom: string;
  1095.  
  1096. begin
  1097.   result := false;
  1098.  
  1099. {From: match if that address found anywhere - so that if they change their}
  1100. {posting software or whatever you'll still find it.}
  1101.  
  1102.   newfrom := from;
  1103.  
  1104.   if caseinsensitiveantikill then
  1105.     newfrom := upper(newfrom);
  1106.  
  1107.   for i := 1 to numfromaks do
  1108.     if not result then
  1109.       result := killmatch(antikillfromsp^[i],newfrom,
  1110.        caseinsensitiveantikill,substringfromantikill);
  1111.  
  1112.   fromantikilled := result;
  1113. end;
  1114. {$endif} {oldkill}
  1115.  
  1116. function artantikilled;
  1117.  
  1118. var
  1119.   result: boolean;
  1120.  
  1121.   whichantikillline: integer;
  1122.   upsubject: string;
  1123.   upfrom: string;
  1124.   whichantikill: integer;
  1125.  
  1126.   oneartheader: string;
  1127.  
  1128.   oneantikillheader: string;
  1129.   oneantikilltext: string;
  1130.  
  1131.   upantikilltext: string;
  1132.  
  1133. begin
  1134.   result := false;
  1135.  
  1136.   upsubject := subject;
  1137.   if caseinsensitiveantikill then
  1138.     upsubject := upper(upsubject);
  1139.  
  1140.   upfrom := from;
  1141.   if caseinsensitiveantikill then
  1142.     upfrom := upper(upfrom);
  1143.  
  1144.   for whichantikill := 1 to groupnumantikills do
  1145.     if not result then
  1146.       begin
  1147.         oneantikillheader := lower(groupantikillsp^[whichantikill].header);
  1148.         oneantikilltext := groupantikillsp^[whichantikill].text;
  1149.         upantikilltext := upper(oneantikilltext);
  1150.  
  1151.         if oneantikillheader='subject' then
  1152.           result := killmatch(oneantikilltext,upsubject,
  1153.            caseinsensitiveantikill,substringsubjectantikill)
  1154.         else if oneantikillheader='from' then
  1155.           result := killmatch(oneantikilltext,upfrom,
  1156.            caseinsensitiveantikill,substringfromantikill)
  1157.         else if oneantikillheader='references' then
  1158.           result := killmatch(upantikilltext,upper(refs),false,true)
  1159.         else if fn<>'' then
  1160.           begin
  1161.             if showdebug('slowkill') then
  1162.               xwritelnssss('going to disk (',fn,') for header ',
  1163.                oneantikillheader);
  1164.  
  1165.             oneartheader := getheaderline(fn,oneantikillheader+':');
  1166.             if caseinsensitiveantikill then
  1167.               oneartheader := upper(oneartheader);
  1168.             if oneartheader<>'' then
  1169.               result := killmatch(
  1170.                oneantikilltext,oneartheader,caseinsensitiveantikill,true);
  1171.           end;
  1172.       end;
  1173.  
  1174.   artantikilled := result;
  1175. end;
  1176.  
  1177. end.
  1178.